package de.akabahn.ebd.stw.zdxfc.prs.tco;

import static de.akabahn.ebd.stw.zdxfc.prs.ZDXFCConstants.BLOCK_1231_MELDER_AN;
import static de.akabahn.ebd.stw.zdxfc.prs.ZDXFCConstants.SPERRE_ZDXFC;

import org.apache.log4j.Logger;

import de.akabahn.ebd.comm.dbd.DBDParameter;
import de.akabahn.ebd.dbd.DBDSubscriptionListener;
import de.akabahn.ebd.stw.zdxfc.prs.tco.elemente.Gleis;
import de.akabahn.ebd.stw.zdxfc.prs.tco.elemente.Signal;
import de.akabahn.ebd.stw.zdxfc.prs.tco.elemente.Weiche;

/**
 * Implementierung des <code>DBDSubscriptionListener</code> interfaces fuer die zentrale Verwaltung der
 * Aenderungen an den abonnierten Variablen.
 * 
 * @author Peter Eimann
 * @since 1.0
 * @version 1.1
 */
public class ZDXFCTcoDispatcher implements DBDSubscriptionListener {

	private final static Logger LOG = Logger.getLogger(ZDXFCTcoDispatcher.class);

	private ZDXFCTcoMain main;

	/**
	 * Initialisierung der Klasse
	 * 
	 * @param main Referenz auf die Hauptklasse
	 */
	public ZDXFCTcoDispatcher(ZDXFCTcoMain main) {
		this.main = main;
	}

	/**
	 * Diese Methode wird vom DBD-Adapter aufgerufen, wenn sich der Wert einer abonnierten Variable
	 * geaendert hat.<br>
	 * Innerhalb der Methode wird ausgewertet, welche Variable sich geaendert hat, um die entsprechende Methode
	 * zur Behandlung der Aenderung aufzurufen:<br>
	 * <ol>
	 * <li>Signal-Haltmelder: <code>onChangeSignalHaltmelder(dbd)</code></li>
	 * <li>Signal-Verschlussmelder: <code>onChangeSignalVerschlussmelder(dbd)</code></li>
	 * <li>Weichen-Gleismelder: <code>onChangeWeichenGleismelder(dbd)</code></li>
	 * <li>Weichen-Lagemelder: <code>onChangeWeichenLagemelder(dbd)</code></li>
	 * <li>Gleismelder: <code>onChangeGleismelder(dbd)</code></li>
	 * </ol>
	 * 
	 * @param dbd Die geaenderte Variable
	 * @see DBDParameter
	 * @see #onChangeSignalHaltmelder(DBDParameter)
	 * @see #onChangeSignalVerschlussmelder(DBDParameter)
	 * @see #onChangeWeichenGleismelder(DBDParameter)
	 * @see #onChangeWeichenLagemelder(DBDParameter)
	 * @see #onChangeGleismelder(DBDParameter)
	 */
	@Override
	public void onChange(DBDParameter dbd) {
		LOG.debug("onChange: " + dbd.toString());
		
		if (dbd.getName().startsWith("S31C")) {
			if (dbd.getName().endsWith("MS")) {
				onChangeSignalHaltmelder(dbd);
			} else if (dbd.getName().endsWith("VS")) {
				onChangeSignalVerschlussmelder(dbd);
			}
		} else if (dbd.getName().startsWith("S31W")) {
			if (dbd.getName().endsWith("MS")) {
				onChangeWeichenGleismelder(dbd);
			} else if (dbd.getName().endsWith("LS")) {
				onChangeWeichenLagemelder(dbd);
			}
		} else if (dbd.getName().startsWith("S31G")) {
			onChangeGleismelder(dbd);
		} else if (dbd.getName().equals(BLOCK_1231_MELDER_AN)) {
			main.getLampe(BLOCK_1231_MELDER_AN).setAusleuchtung(dbd.getValue());
		} else if (dbd.getName().equals(SPERRE_ZDXFC)) {
			main.setSperreAktiv(dbd.getValue() != 0);
		}

		main.repaint();
	}

	/**
	 * Die Ausleuchtung eines Signal-Haltmelders hat sich geaendert:
	 * <ul>
	 * <li>Aufruf von <code>Signal.setAusleuchtungHaltmelder()</code></li>
	 * </ul>
	 * 
	 * @param dbd Die geaenderte Variable
	 * @see Signal#setAusleuchtungHaltmelder(int)
	 */
	private void onChangeSignalHaltmelder(DBDParameter dbd) {
		LOG.debug("onChangeSignalHaltmelder: " + dbd.toString());
		main.getSignal(dbd.getName()).setAusleuchtungHaltmelder(dbd.getValue());
	}

	/**
	 * Die Ausleuchtung eines Signal-Verschlussmelders hat sich geaendert:
	 * <ul>
	 * <li>Aufruf von <code>Signal.setAusleuchtungVerschlussmelder()</code></li>
	 * </ul>
	 * 
	 * @param dbd Die geaenderte Variable
	 * @see Signal#setAusleuchtungVerschlussmelder(int)
	 */
	private void onChangeSignalVerschlussmelder(DBDParameter dbd) {
		LOG.debug("onChangeSignalVerschlussmelder: " + dbd.toString());
		main.getSignal(dbd.getName()).setAusleuchtungVerschlussmelder(dbd.getValue());
	}

	/**
	 * Die Ausleuchtung eines Weichen-Gleismelders hat sich geaendert:
	 * <ul>
	 * <li>Aufruf von <code>Weiche.setAusleuchtungGleismelder()</code></li>
	 * </ul>
	 * 
	 * @param dbd Die geaenderte Variable
	 * @see Weiche#setAusleuchtungGleismelder(int)
	 */
	private void onChangeWeichenGleismelder(DBDParameter dbd) {
		LOG.debug("onChangeWeichenGleismelder: " + dbd.toString());
		main.getWeiche(dbd.getName()).setAusleuchtungGleismelder(dbd.getValue());
	}

	/**
	 * Die Ausleuchtung eines Weichen-Lagemelders hat sich geaendert:
	 * <ul>
	 * <li>Aufruf von <code>Weiche.setAusleuchtungLagemelder()</code></li>
	 * </ul>
	 * 
	 * @param dbd Die geaenderte Variable
	 * @see Weiche#setAusleuchtungLagemelder(int)
	 */
	private void onChangeWeichenLagemelder(DBDParameter dbd) {
		LOG.debug("onChangeWeichenLagemelder: " + dbd.toString());
		main.getWeiche(dbd.getName()).setAusleuchtungLagemelder(dbd.getValue());
	}

	/**
	 * Die Ausleuchtung eines Gleismelders hat sich geaendert:
	 * <ul>
	 * <li>Aufruf von <code>Gleis.setAusleuchtung()</code></li>
	 * </ul>
	 * 
	 * @param dbd Die geaenderte Variable
	 * @see Gleis#setAusleuchtung(int)
	 */
	private void onChangeGleismelder(DBDParameter dbd) {
		LOG.debug("onChangeGleismelder: " + dbd.toString());
		main.getGleis(dbd.getName()).setAusleuchtung(dbd.getValue());
	}
}
